package org.freez4.spring.configuration.metadata;

import org.freez4.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.util.ObjectUtils;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Bean 配置元信息示例。
 *
 * @author 阿坤同学
 * @date 2024/1/9 11:06 AM
 */
public class BeanConfigurationMetadataDemo {

    private static final Logger logger = Logger.getLogger(BeanConfigurationMetadataDemo.class.getName());


    public static void main(String[] args) {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
        beanDefinitionBuilder.addPropertyValue("name", "阿坤");
        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
        // 设置附加属性，可以辅助bean初始化（不影响 Bean populate、initialize）
        beanDefinition.setAttribute("name", "free");
        // 当前 BeanDefinition 来自于何方（辅助作用）
        beanDefinition.setSource(BeanConfigurationMetadataDemo.class);

        DefaultListableBeanFactory beanFactory = getDefaultListableBeanFactory();
        // 注册 User 的 BeanDefinition
        beanFactory.registerBeanDefinition("user", beanDefinition);
        User user = beanFactory.getBean("user", User.class);
        logger.log(Level.INFO, () -> "userBean:" + user);
    }

    private static DefaultListableBeanFactory getDefaultListableBeanFactory() {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) {
                // 过滤掉非User 类型的Bean
                if (ObjectUtils.nullSafeEquals("user", beanName) && User.class.equals(bean.getClass())) {
                    BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
                    if (BeanConfigurationMetadataDemo.class.equals(bd.getSource())) { // 通过 source 判断来
                        // 属性（存储）上下文
                        String name = (String) bd.getAttribute("name"); // 就是 "free"
                        User user = (User) bean;
                        user.setName(name);
                    }
                }
                return bean;
            }
        });
        return beanFactory;
    }
}
